package com.example.aopdemo.aspect;

import com.example.aopdemo.annotation.AspectAction;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @Package: com.example.aopdemo.aspect
 * @ClassName: LogAspect
 * @Author: Think
 * @CreateTime: 2021/8/18 9:12
 * @Description: 切面定义
 */
@Aspect
@Component
public class LogAspect {

    /**
     * 声明切点表达式
     * 方法名称随意起
     */
/*    @Pointcut("execution(* com.example.aopdemo.controller.HelloController.getHello(..))")
    public void pointCut(){}*/

    /**
     * 前置通知
     * 在方法执行之前执行
     */
/*    @Before("execution(* com.example.aopdemo.controller.HelloController.getHello(..))")
    public void before() {
        System.out.println("before");
    }*/

    /**
     * 后置通知
     * 在方法执行之后
     */
/*    @After("execution(* com.example.aopdemo.controller.HelloController.getHello(..))")
    public void after() {
        System.out.println("after");
    }*/

    /**
     * 返回通知
     * 在方法执行之后，返回之前执行
     */
/*    @AfterReturning("execution(* com.example.aopdemo.controller.HelloController.getHello(..))")
    public void afterReturing() {
        System.out.println("afterReturning");
    }*/

    /**
     * 异常通知
     * 在方法抛出异常之后执行
     */
/*    @AfterThrowing("execution(* com.example.aopdemo.controller.HelloController.getHello(..))")
    public void afterThrowing() {
        System.out.println("afterThrowing");
    }*/

    /**
     * 环绕通知
     * 能够代替其它四种通知使用
     */
/*    @Around("pointCut()")
    public void around(ProceedingJoinPoint joinPoint) {
        System.out.println("前置通知！");
        try {
            joinPoint.proceed();
            System.out.println("返回通知！");
        } catch (Throwable throwable) {
            System.out.println("异常通知！");
        } finally {
            System.out.println("后置通知！");
        }
    }*/

    @Pointcut("@annotation(com.example.aopdemo.annotation.AspectAction)")
    public void pointCut(){}

    @Around("pointCut()")
    public String around(ProceedingJoinPoint joinPoint) {
        Object result = null;
        System.out.println("前置通知！");
        try {
            result = (String)joinPoint.proceed();
            System.out.println("返回通知！");
        } catch (Throwable throwable) {
            System.out.println("异常通知！");
        } finally {
            System.out.println("后置通知！");
        }
        return result + " from aop";
    }
}
